/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有，侵权必究！
 */

package cc.ls51.cms.shiro;

import cc.ls51.exception.BusinessException;
import cc.ls51.form.UserLoginForm;
import cc.ls51.modules.SysMenu.entity.SysMenu;
import cc.ls51.modules.SysMenu.service.ISysMenuService;
import cc.ls51.modules.SysUser.entity.SysUser;
import cc.ls51.modules.SysUser.service.ISysUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 认证
 *
 * @author Mark sunlightcs@gmail.com
 */
@Component
public class UserRealm extends AuthorizingRealm {
	Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
	ISysMenuService sysMenuService;
    @Autowired
	ISysUserService sysUserService;

    /**
     * 授权(验证权限时调用) 鉴权调用
     */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		logger.info("doGetAuthorizationInfo 认证授权");
		SysUser user = (SysUser)principals.getPrimaryPrincipal();
		Long userId = user.getId();
		//系统管理员，拥有最高权限
//		if(userId == Constant.SUPER_ADMIN){
//			List<SysMenuEntity> menuList = sysMenuDao.selectList(null);
//			permsList = new ArrayList<>(menuList.size());
//			for(SysMenuEntity menu : menuList){
//				permsList.add(menu.getPerms());
//			}
//		}else{
//			permsList = sysUserDao.queryAllPerms(userId);
//		}

		//用户权限列表
		List<SysMenu> permsList = sysMenuService.getList();
		Set<String> permsSet = new HashSet<>();
		for(SysMenu perms : permsList){
			if(StringUtils.isBlank(perms.getAccessUrl())){
				continue;
			}
			permsSet.add(perms.getAccessUrl());
		}
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

		info.setStringPermissions(permsSet);
		return info;
	}

	/**
	 * 认证(登录时调用)
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		logger.info("doGetAuthenticationInfo 登陆授权");
		UsernamePasswordToken token = (UsernamePasswordToken)authcToken;
		String username = token.getUsername();
		UserLoginForm userLoginForm = new UserLoginForm();
		userLoginForm.setUsername(username);
		//查询用户信息
		SysUser user = null;
		try {
			user = sysUserService.getUserByUsername(userLoginForm);
		} catch (BusinessException e) {
			throw new AuthenticationException(e.getErrorMsg());
		}
		String userPwd = String.valueOf(token.getPassword());
		if(!ShiroUtils.sha256(userPwd,user.getSalt()).equals(user.getPassword())){
			throw new AuthenticationException("账号或密码不正确1");
		}
		//账号不存在
		if(user == null) {
			throw new UnknownAccountException("账号或密码不正确2");
		}
		//账号锁定
		if(user.getStatus() == 0){
			throw new LockedAccountException("账号已被锁定,请联系管理员3");
		}
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());
		return info;
	}

	@Override
	public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
		HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
		shaCredentialsMatcher.setHashAlgorithmName(ShiroUtils.hashAlgorithmName);
		shaCredentialsMatcher.setHashIterations(ShiroUtils.hashIterations);
		super.setCredentialsMatcher(shaCredentialsMatcher);
	}
	public static void main(String[] args){
		String stmp = ShiroUtils.sha256("123456","1");
		System.out.println(stmp);
	}
}
